package table.models;

import java.util.ArrayList;
import java.util.Vector;
import java.util.concurrent.Semaphore;

import javax.swing.table.AbstractTableModel;

public class ParticipantsTableModel extends AbstractTableModel {
	private int columnCount;
	private ArrayList < Object [] > rowData;
	private String [] columnNames = new String [this.columnCount];
	private int ageClassColumnIndex;
	private int bowCathegoryColumnIndex;
	private int genderColumnIndex;
	private final Semaphore semephore = new Semaphore(1);

	public ParticipantsTableModel(String [] columnNames) {
		this.columnNames = columnNames;
		this.bowCathegoryColumnIndex = 5;
		this.ageClassColumnIndex = 6;
		this.genderColumnIndex = 8;
		this.columnCount = this.columnNames.length;
		this.rowData = new ArrayList < Object [] >();
	}

	public Semaphore getSemaphore() {
		return this.semephore;
	}

	public ParticipantsTableModel(String [] columnNames, int bowCathegoryColumnIndex, int ageClassColumnIndex, int genderColumnIndex) {
		this.columnNames = columnNames;
		this.bowCathegoryColumnIndex = bowCathegoryColumnIndex;
		this.ageClassColumnIndex = ageClassColumnIndex;
		this.genderColumnIndex = genderColumnIndex;
		this.columnCount = this.columnNames.length;
		this.rowData = new ArrayList < Object [] >();
	}

	public int getGenderColumnIndex() {
		return this.genderColumnIndex;
	}

	public void setGenderColumnIndex(int genderColumnIndex) {
		this.genderColumnIndex = genderColumnIndex;
	}

	public void replaceRow(int rowNumber, Object [] newRowData) {
		this.rowData.set(rowNumber, newRowData);
		this.fireTableDataChanged();
	}

	@Override
	public String getColumnName(int column) {
		return this.columnNames [column];
	}

	@Override
	public boolean isCellEditable(int row, int col) {
		return false;
	}

	@Override
	public int getColumnCount() {
		return this.columnCount;
	}

	@Override
	public int getRowCount() {
		return this.rowData.size();
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		if (rowIndex < this.rowData.size()) {
			return this.rowData.get(rowIndex) [columnIndex];
		} else {
			return null;
		}
	}

	@Override
	public void setValueAt(Object value, int row, int col) {
		try {
			this.semephore.acquire();
			while (this.getRowCount() < row) {
				this.addRow();
			}
			this.rowData.get(row) [col] = value;
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			this.semephore.release();
		}
		this.fireTableCellUpdated(row, col);
	}

	public void addRow() {
		this.rowData.add(new Object [this.columnCount]);
		this.fireTableRowsInserted(this.rowData.size() - 1, this.rowData.size() - 1);
	}

	public void setColumnIdentifiers(String [] strings) {
		this.columnNames = strings;
		this.columnCount = strings.length;
	}

	public void addRow(Object [] objects) {
		this.rowData.add(objects);
	}

	@Override
	public Class getColumnClass(int c) {
		return this.getValueAt(0, c).getClass();
	}

	public Object [] getRowData(int row) {
		return this.rowData.get(row);
	}

	public void removeRow(int row) {
		this.rowData.remove(row);
		this.fireTableDataChanged();
	}

	public void removeData() {
		this.rowData = new ArrayList < Object [] >();
	}

	public int getRowForPlayer(int playerID) {
		int toReturn = 0;
		try {
			this.semephore.acquire();
			int row = 0;
			for (int i = 0; i < this.rowData.size(); i++) {
				if (Integer.parseInt(this.rowData.get(i) [0].toString()) == playerID) {
					toReturn = row;
					break;
				}
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			this.semephore.release();
		}
		return toReturn;
	}

	public int getAgeClassColumnIndex() {
		return this.ageClassColumnIndex;
	}

	public void setAgeClassColumnIndex(int ageClassColumnIndex) {
		this.ageClassColumnIndex = ageClassColumnIndex;
	}

	public int getCathegoryColumnIndex() {
		return this.bowCathegoryColumnIndex;
	}

	public void setBowCathegoryColumnIndex(int cathegoryColumnIndex) {
		this.bowCathegoryColumnIndex = cathegoryColumnIndex;
	}

	public Vector getDataVector() {
		Vector toReturn = new Vector(this.getRowCount());
		for (int i = 0; i < toReturn.size(); i++) {
			toReturn.set(i, this.getRowVector(i));
		}
		return toReturn;
	}

	public Vector getRowVector(int row) {
		Vector toReturn = new Vector < Object >(this.getColumnCount());
		for (int i = 0; i < toReturn.size(); i++) {
			toReturn.set(i, this.getValueAt(row, i));
		}
		return toReturn;
	}
}
